<template>
  <div
    :class="[
      'media-card',
      `media-card--${size}`,
      `media-card--${variant}`,
      { 'media-card--selected': selected },
      { 'media-card--hover': hover }
    ]"
    @click="$emit('click', $event)"
    @mouseenter="handleMouseEnter"
    @mouseleave="handleMouseLeave"
  >
    <!-- 媒体预览区域 -->
    <div class="media-card__preview">
      <!-- 图片预览 -->
      <div v-if="media.fileType === 'image'" class="media-preview">
        <img
          :alt="media.originalFileName || media.name"
          :src="media.thumbnailUrl || media.fileUrl"
          class="media-image"
          loading="lazy"
          @error="handleImageError"
        />
      </div>

      <!-- 视频预览 -->
      <div v-else-if="media.fileType === 'video'" class="media-preview video-preview">
        <img
          v-if="media.thumbnailUrl"
          :alt="media.originalFileName || media.name"
          :src="media.thumbnailUrl"
          class="video-thumbnail"
          loading="lazy"
        />
        <div v-else class="video-placeholder">
          <tiny-icon-video />
        </div>

        <!-- 视频时长 -->
        <div v-if="media.duration" class="media-duration">
          {{ formatDuration(media.duration) }}
        </div>

        <!-- 播放按钮 -->
        <div class="play-overlay">
          <tiny-icon-play />
        </div>
      </div>

      <!-- 音频预览 -->
      <div v-else-if="media.fileType === 'audio'" class="media-preview audio-preview">
        <div class="audio-icon">
          <tiny-icon-music />
        </div>
        <div class="audio-waveform">
          <div v-for="i in 5" :key="i" class="wave-bar"></div>
        </div>
        <div v-if="media.duration" class="media-duration">
          {{ formatDuration(media.duration) }}
        </div>
      </div>

      <!-- 文档预览 -->
      <div v-else class="media-preview document-preview">
        <div :class="media.fileFormat" class="document-icon">
          <component :is="getFileIcon(media.fileFormat)" />
        </div>
        <div class="document-ext">{{ media.fileFormat?.toUpperCase() }}</div>
      </div>

      <!-- 状态标识 -->
      <div v-if="media.isFavorite" class="status-badge favorite-badge">
        <tiny-icon-heart-fill />
      </div>

      <div v-if="media.aiTags" class="status-badge ai-badge">
        <tiny-icon-magic />
      </div>

      <!-- 选择框 -->
      <div v-if="selectable" class="selection-checkbox">
        <div :class="{ checked: selected }" class="checkbox-inner">
          <tiny-icon-check v-if="selected" />
        </div>
      </div>

      <!-- 悬浮操作按钮 -->
      <div v-if="showActions && isHovering" class="action-buttons">
        <tiny-button
          v-if="actions.includes('download')"
          class="action-btn"
          size="mini"
          type="text"
          @click.stop="$emit('download', media)"
        >
          <tiny-icon-download />
        </tiny-button>

        <tiny-button
          v-if="actions.includes('share')"
          class="action-btn"
          size="mini"
          type="text"
          @click.stop="$emit('share', media)"
        >
          <tiny-icon-share />
        </tiny-button>

        <tiny-button
          v-if="actions.includes('favorite')"
          class="action-btn"
          size="mini"
          type="text"
          @click.stop="$emit('favorite', media)"
        >
          <tiny-icon-heart :class="{ 'favorited': media.isFavorite }" />
        </tiny-button>

        <tiny-button
          v-if="actions.includes('more')"
          class="action-btn"
          size="mini"
          type="text"
          @click.stop="$emit('more', media)"
        >
          <tiny-icon-more />
        </tiny-button>
      </div>
    </div>

    <!-- 媒体信息区域 -->
    <div v-if="showInfo" class="media-card__info">
      <div :title="media.originalFileName || media.name" class="media-title">
        {{ media.originalFileName || media.name }}
      </div>

      <div v-if="showMeta" class="media-meta">
        <span class="media-size">{{ formatFileSize(media.fileSize || media.size) }}</span>
        <span class="media-date">{{ formatDate(media.createTime || media.uploadedAt) }}</span>
      </div>

      <!-- AI标签 -->
      <div v-if="media.aiTags && showAiTags" class="ai-tags">
        <tiny-tag
          v-for="tag in media.aiTags.split(',').slice(0, 2)"
          :key="tag.trim()"
          class="ai-tag"
          size="mini"
          type="info"
        >
          {{ tag.trim() }}
        </tiny-tag>
        <tiny-tag
          v-if="media.aiTags.split(',').length > 2"
          class="more-tags"
          size="mini"
          type="default"
        >
          +{{ media.aiTags.split(',').length - 2 }}
        </tiny-tag>
      </div>
    </div>

    <!-- 上传进度 -->
    <div v-if="media.uploadProgress !== undefined" class="upload-progress">
      <div class="progress-bg">
        <div
          :style="{ width: media.uploadProgress + '%' }"
          class="progress-fill"
        ></div>
      </div>
      <span class="progress-text">{{ media.uploadProgress }}%</span>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {ref} from 'vue'

// Props
interface Props {
  media: any
  size?: 'small' | 'medium' | 'large'
  variant?: 'default' | 'compact' | 'detailed'
  selected?: boolean
  selectable?: boolean
  hover?: boolean
  showInfo?: boolean
  showMeta?: boolean
  showAiTags?: boolean
  showActions?: boolean
  actions?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  size: 'medium',
  variant: 'default',
  selected: false,
  selectable: false,
  hover: true,
  showInfo: true,
  showMeta: true,
  showAiTags: true,
  showActions: true,
  actions: () => ['download', 'share', 'favorite']
})

// Emits
const emit = defineEmits<{
  'click': [event: Event]
  'download': [media: any]
  'share': [media: any]
  'favorite': [media: any]
  'more': [media: any]
}>()

// 响应式数据
const isHovering = ref(false)

// 事件处理
const handleMouseEnter = () => {
  if (props.hover) {
    isHovering.value = true
  }
}

const handleMouseLeave = () => {
  isHovering.value = false
}

const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  img.style.display = 'none'
}

// 工具函数
const formatFileSize = (bytes: number): string => {
  if (!bytes) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}

const formatDate = (dateStr: string): string => {
  if (!dateStr) return ''
  const date = new Date(dateStr)
  const now = new Date()
  const diffTime = now.getTime() - date.getTime()
  const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24))

  if (diffDays === 0) return '今天'
  if (diffDays === 1) return '昨天'
  if (diffDays < 7) return `${diffDays}天前`
  if (diffDays < 30) return `${Math.floor(diffDays / 7)}周前`

  return date.toLocaleDateString('zh-CN')
}

const formatDuration = (seconds: number): string => {
  const mins = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

const getFileIcon = (format: string) => {
  const iconMap: Record<string, string> = {
    pdf: 'tiny-icon-file-pdf',
    doc: 'tiny-icon-file-word',
    docx: 'tiny-icon-file-word',
    xls: 'tiny-icon-file-excel',
    xlsx: 'tiny-icon-file-excel',
    ppt: 'tiny-icon-file-ppt',
    pptx: 'tiny-icon-file-ppt',
    txt: 'tiny-icon-file-text',
    zip: 'tiny-icon-file-zip',
    rar: 'tiny-icon-file-zip'
  }
  return iconMap[format] || 'tiny-icon-file'
}
</script>

<style lang="scss" scoped>
@use 'sass:color';
.media-card {
  position: relative;
  background: white;
  border-radius: $radius-xl;
  overflow: hidden;
  border: 1px solid $gray-200;
  transition: all $duration-normal $ease-out-quart;
  cursor: pointer;

  &--small {
    .media-card__preview {
      aspect-ratio: 1;
    }

    .media-card__info {
      padding: $spacing-3;

      .media-title {
        font-size: $text-sm;
        -webkit-line-clamp: 1;
      }
    }
  }

  &--medium {
    .media-card__preview {
      aspect-ratio: 4/3;
    }

    .media-card__info {
      padding: $spacing-4;
    }
  }

  &--large {
    .media-card__preview {
      aspect-ratio: 16/10;
    }

    .media-card__info {
      padding: $spacing-6;

      .media-title {
        font-size: $text-lg;
        -webkit-line-clamp: 3;
      }
    }
  }

  &--compact {
    .media-card__info {
      padding: $spacing-2;

      .media-meta {
        font-size: $text-xs;
      }
    }
  }

  &--detailed {
    .ai-tags {
      margin-top: $spacing-3;
    }
  }

  &--hover:hover {
    transform: translateY(-4px);
    box-shadow: $shadow-lg;
    border-color: $primary-200;
  }

  &--selected {
    border-color: $primary-500;
    box-shadow: 0 0 0 3px rgba($primary-500, 0.1);

    .selection-checkbox .checkbox-inner {
      background: $primary-500;
      border-color: $primary-500;
      color: white;
    }
  }

  .media-card__preview {
    position: relative;
    overflow: hidden;

    .media-preview {
      width: 100%;
      height: 100%;
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;

      .media-image,
      .video-thumbnail {
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform $duration-normal ease;
      }

      &.video-preview {
        background: $gray-100;

        .video-placeholder {
          font-size: 48px;
          color: $gray-400;
        }

        .play-overlay {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          width: 60px;
          height: 60px;
          background: rgba(0, 0, 0, 0.7);
          border-radius: $radius-full;
          display: flex;
          align-items: center;
          justify-content: center;
          color: white;
          font-size: 24px;
          opacity: 0;
          transition: opacity $duration-normal ease;
        }

        &:hover .play-overlay {
          opacity: 1;
        }
      }

      &.audio-preview {
        background: linear-gradient(135deg, $media-audio 0%, color.adjust($media-audio, $lightness: 20%) 100%);
        color: white;
        flex-direction: column;

        .audio-icon {
          font-size: 48px;
          margin-bottom: $spacing-2;
        }

        .audio-waveform {
          display: flex;
          gap: 2px;
          margin-bottom: $spacing-2;

          .wave-bar {
            width: 3px;
            background: rgba(255, 255, 255, 0.8);
            border-radius: $radius-full;
            animation: wave-animation 1.5s infinite;

            &:nth-child(1) { height: 16px; animation-delay: 0s; }
            &:nth-child(2) { height: 12px; animation-delay: 0.1s; }
            &:nth-child(3) { height: 20px; animation-delay: 0.2s; }
            &:nth-child(4) { height: 8px; animation-delay: 0.3s; }
            &:nth-child(5) { height: 14px; animation-delay: 0.4s; }
          }
        }
      }

      &.document-preview {
        background: linear-gradient(135deg, $media-document 0%, color.adjust($media-document, $lightness: 20%) 100%);
        color: white;
        flex-direction: column;

        .document-icon {
          font-size: 48px;
          margin-bottom: $spacing-2;
        }

        .document-ext {
          font-size: $text-sm;
          font-weight: $font-semibold;
          padding: $spacing-1 $spacing-3;
          background: rgba(255, 255, 255, 0.2);
          border-radius: $radius-sm;
        }
      }

      .media-duration {
        position: absolute;
        bottom: $spacing-2;
        right: $spacing-2;
        padding: 2px $spacing-2;
        background: rgba(0, 0, 0, 0.8);
        color: white;
        border-radius: $radius-sm;
        font-size: $text-xs;
      }
    }

    .status-badge {
      position: absolute;
      top: $spacing-3;
      width: 28px;
      height: 28px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: $radius-full;
      color: white;
      font-size: 14px;

      &.favorite-badge {
        right: $spacing-3;
        background: $error-500;
      }

      &.ai-badge {
        right: $spacing-16;
        background: $media-video;
        box-shadow: 0 0 10px rgba($media-video, 0.3);
      }
    }

    .selection-checkbox {
      position: absolute;
      top: $spacing-3;
      left: $spacing-3;
      z-index: 10;

      .checkbox-inner {
        width: 24px;
        height: 24px;
        background: rgba(255, 255, 255, 0.9);
        border: 2px solid $gray-300;
        border-radius: $radius-sm;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all $duration-normal ease;

        &.checked {
          background: $primary-500;
          border-color: $primary-500;
          color: white;
        }
      }
    }

    .action-buttons {
      position: absolute;
      top: $spacing-3;
      right: $spacing-3;
      display: flex;
      gap: $spacing-2;
      z-index: 10;

      .action-btn {
        width: 32px;
        height: 32px;
        border-radius: $radius-md;
        background: rgba(255, 255, 255, 0.95);
        backdrop-filter: blur(8px);
        border: none;

        &:hover {
          background: white;
          transform: scale(1.1);
        }

        .tiny-icon {
          font-size: 14px;

          &.favorited {
            color: $error-500;
          }
        }
      }
    }
  }

  .media-card__info {
    .media-title {
      font-size: $text-base;
      font-weight: $font-semibold;
      color: $gray-800;
      margin-bottom: $spacing-2;
      line-height: $leading-tight;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    .media-meta {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-size: $text-sm;
      color: $gray-600;
      margin-bottom: $spacing-2;

      .media-size {
        font-weight: $font-medium;
      }
    }

    .ai-tags {
      display: flex;
      flex-wrap: wrap;
      gap: $spacing-1;

      .ai-tag,
      .more-tags {
        font-size: 10px;
      }
    }
  }

  .upload-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: $spacing-2;
    background: rgba(0, 0, 0, 0.8);
    color: white;

    .progress-bg {
      height: 4px;
      background: rgba(255, 255, 255, 0.3);
      border-radius: $radius-full;
      overflow: hidden;
      margin-bottom: $spacing-1;

      .progress-fill {
        height: 100%;
        background: $success-500;
        transition: width $duration-normal ease;
      }
    }

    .progress-text {
      font-size: $text-xs;
    }
  }
}

// 动画
@keyframes wave-animation {
  0%, 100% {
    transform: scaleY(1);
  }
  50% {
    transform: scaleY(1.5);
  }
}

// 暗色主题
[data-theme="dark"] {
  .media-card {
    background: $dark-100;
    border-color: $dark-200;

    .media-card__info {
      .media-title {
        color: $dark-800;
      }

      .media-meta {
        color: $dark-600;
      }
    }
  }
}
</style>
